# this script parses OpenTherm signal coming from sigrok
# this script expects one value per input line
# llong and lend are such that it works when sampling is done at 20kHz

function debugline() {
   ##print "frame:", frame, "state:", s, "length:", l, "height:", h, "now read value", $1
}

BEGIN {

   # NOMENCLATURE for this script:

   # signal:  11111111111111110000000111111100000000000000111111111111111111111
   #          ----------------_______---------------------_____________________
   # status s:    WAIT         POST    PREP   POST   PREP  POST   PREP    WAIT
   # bits:                    0             0             1
   # segment borders:         |      |      |      |      |
     
   #  signal = lines each consisting of a 0 or a 1, input for this script, output from sigrok
   #  status = status of this script, can be WAIT, POST or PREP (see below)
   #   value: a line from signal, can be 0 or 1
   #     bit: 0 or 1 as calculated by this scippt; decoded from signal
   # segment: 2 or more consecutive 0's in signal, or 2 or more consecutive 1's in signal

   # meaning of the values for status s:
   # "WAIT": waiting for a next frame or EOF
   # "POST": just had a value change that constituted a bit
   # "PREP": preparing for a new bit
   #

   s = "WAIT"       # status
   h = 0            # height of current segment
   l = 0            # length of current segment
   llong = 12       # length at which POST becomes PREP if there is no value change
   lend  = 23       # length at which PREP becomes WAIT; frame is fully decoded 
   otlength = 34    # length of OpenTherm frame; always 1+32+1
   frame = ""       # current frame contents
}

{
   debugline()

   if ( $1 == h ) {
      # no value change
      l++ 
      if ( s == "POST"  && l >= llong ) { s = "PREP" }
      if ( s == "PREP"  && l >= lend  ) { s = "WAIT" }
   }
   else {
      # value change
      # read next line to check if it is just singular bitflip
      ret = getline ; if ( ret <= 0 ) { exit } else { debugline() }
      if ( $1 == h ) { 
         # ignore singular bitflip; it is not a real value change
         l += 2
         if ( s == "POST" && l >= llong ) { s = "PREP" }
         if ( s == "PREP"  && l >= lend  ) { s = "WAIT" }
      } else {
         # a value change to be registered
         if ( s == "POST" ) {
            # preparing for a new bit with same value as previous bit
            s = "PREP"
            h = $1
            l = 2
         } else {
            # we are in "PREP" or in "WAIT"
            # we encountered a value change that resembles a bit
            frame = frame $1
            s = "POST"
            h = $1
            l = 2
         }
      }
   }

   if ( s == "WAIT" && frame != "" ) {
      # frame is fully decoded and needs printing
      if  ( length(frame) == otlength ) {
         # a valid OpenTherm frame
         print substr(frame,1,2), substr(frame,3,3), substr(frame,6,4), substr(frame,10,8), substr(frame,18,16), substr(frame,34,1)
      }
      # initialise next frame
      frame = ""
   }

}


